﻿//#include <iostream>
//using namespace std;
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	// 这⾥可以看到如果发⽣除0错误抛出异常，另外下⾯的array1和array2没有得到释放。
//	// 所以这⾥捕获异常后并不处理异常，异常还是交给外⾯处理，这⾥捕获了再重新抛出去。
//	// 但是如果array2new的时候抛异常呢，就还需要套⼀层捕获释放逻辑，这⾥更好解决⽅案
//	// 是智能指针，否则代码太挫了
//	int* array1 = new int[10];
//	int* array2 = new int[10]; // 抛异常呢?
//	try
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Divide(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array1 << endl;
//		cout << "delete []" << array2 << endl;
//		delete[] array1;
//		delete[] array2;
//		throw; // 异常重新抛出，捕获到什么抛出什么
//	}
//	// ...
//	cout << "delete []" << array1 << endl;
//	delete[] array1;
//	cout << "delete []" << array2 << endl;
//	delete[] array2;
//}
//int main()
//{
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//	return 0;
//}



//#include <iostream>
//using namespace std;
//template<class T>
//class SmartPtr
//{
//public:
//	// RAII
//	SmartPtr(T* ptr)
//		:_ptr(ptr)
//	{}
//	~SmartPtr()
//	{
//		cout << "delete[] " << _ptr << endl;
//		delete[] _ptr;
//	}
//	// 重载运算符，模拟指针的⾏为，⽅便访问资源
//	T& operator*()
//	{
//		return *_ptr;
//	}
//	T* operator->()
//	{
//		return _ptr;
//	}
//	T& operator[](size_t i)
//	{
//		return _ptr[i];
//	}
//private:
//	T* _ptr;
//};
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	// 这⾥使⽤RAII的智能指针类管理new出来的数组以后，程序简单多了
//	SmartPtr<int> sp1 = new int[10];
//	SmartPtr<int> sp2 = new int[10];
//	for (size_t i = 0; i < 10; i++)
//	{
//		sp1[i] = sp2[i] = i;
//	}
//	int len, time;
//	cin >> len >> time;
//	cout << Divide(len, time) << endl;
//}
//int main()
//{
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//	return 0;
//}


//#include <iostream>
//#include <memory>
//using namespace std;
//struct Date
//{
//	int _year;
//	int _month;
//	int _day;
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year), _month(month)
//		, _day(day)
//	{}
//	~Date()
//	{
//		cout << "~Date()" << endl;
//	}
//};
//int main()
//{
//	auto_ptr<Date> ap1(new Date);
//
//	// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
//	auto_ptr<Date> ap2(ap1);
//	// 空指针访问error，ap1对象已经悬空
//	//ap1->_year++;
//
//	unique_ptr<Date> up1(new Date);
//	// 不⽀持拷⻉
//	//unique_ptr<Date> up2(up1);
//	
//	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
//	unique_ptr<Date> up3(move(up1));
//	shared_ptr<Date> sp1(new Date);
//
//	// ⽀持拷⻉
//	shared_ptr<Date> sp2(sp1);
//	shared_ptr<Date> sp3(sp2);
//	//引用计数
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//
//	// ⽀持移动，但是移动后sp1也悬空，所以使⽤移动要谨慎
//	shared_ptr<Date> sp4(move(sp1));
//	return 0;
//}

//
//#define _CRT_SECURE_NO_WARNINGS 1
//#include <iostream>
//#include <memory>
//using namespace std;
//struct Date
//{
//	int _year;
//	int _month;
//	int _day;
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year), _month(month)
//		, _day(day)
//	{}
//	~Date()
//	{
//		cout << "~Date()" << endl;
//	}
//};
//template<class T>
//void DeleteArrayFunc(T* ptr)
//{
//	delete[] ptr;
//}
//
//template<class T>
//class DeleteArray
//{
//public:
//	void operator()(T* ptr)
//	{
//		delete[] ptr;
//	}
//};
//class Fclose
//{
//public:
//	void operator()(FILE* ptr)
//	{
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//	}
//};
////unique_ptr定制删除器 建议仿函数 ；shared_ptr定制删除器 都可以 相对建议lambda
//int main()
//{
//	// 这样实现程序会崩溃
//	// unique_ptr<Date> up1(new Date[10]);
//	// shared_ptr<Date> sp1(new Date[10]);
//	
//	// 解决⽅案1
//	// 因为new[]经常使⽤，所以unique_ptr和shared_ptr
//	// 实现了⼀个特化版本，这个特化版本析构时⽤的delete[]
//	unique_ptr<Date[]> up1(new Date[5]);
//	shared_ptr<Date[]> sp1(new Date[5]);
//
//	// 解决⽅案2
//    // 仿函数对象做删除器
//    // unique_ptr<Date, DeleteArray<Date>> up2(new Date[5], DeleteArray<Date>());
//	// unique_ptr和shared_ptr⽀持删除器的⽅式有所不同
//	// unique_ptr是在类模板参数⽀持的，shared_ptr是构造函数参数⽀持的
//	// 这⾥没有使⽤相同的⽅式还是挺坑的
//	// 使⽤仿函数unique_ptr可以不在构造函数传递，因为仿函数类型构造的对象直接就可以调⽤
//	// 但是下⾯的函数指针和lambda的类型不可以
//	unique_ptr<Date, DeleteArray<Date>> up2(new Date[5]);
//	shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());
//
//	// 函数指针做删除器
//	unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
//	shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);
//
//	// lambda表达式做删除器
//	auto delArrOBJ = [](Date* ptr) {delete[] ptr; };
//	//decltype与auto关键字一样，用于进行编译时类型推导,
//	//总是以一个普通表达式作为参数，返回该表达式的类型,
//	//而且decltype并不会对表达式进行求值
//	unique_ptr<Date, decltype(delArrOBJ)> up4(new Date[5], delArrOBJ);
//	shared_ptr<Date> sp4(new Date[5], delArrOBJ);
//
//	// 实现其他资源管理的删除器
//	shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
//	shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//		});
//	return 0;
//}
//
//int main()
//{
//	shared_ptr<Date> sp1(new Date(2024, 9, 11));
//	shared_ptr<Date> sp2 = make_shared<Date>(2024, 9, 11);
//	auto sp3 = make_shared<Date>(2024, 9, 11);
//	shared_ptr<Date> sp4;
//	// if (sp1.operator bool())
//	if (sp1)
//		cout << "sp1 is not nullptr" << endl;
//	if (!sp4)
//		cout << "sp1 is nullptr" << endl;
//
//	//shared_ptr 和 unique_ptr 都得构造函数都使⽤explicit修饰
//	//防⽌普通指针隐式类型转换成智能指针对象
//	//不存在从"Date*"转换到"std:shared_ptr<Date>"的适当构造函数
//	//报错
//	//shared_ptr<Date> sp5 = new Date(2024, 9, 11);
//	//不存在从"Date*"转换到"std:unique_ptr<Date,std::default_delete < Date >> "的适当构造函数
//	//unique_ptr<Date> sp6 = new Date(2024, 9, 11);
//	return 0;
//}
#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<memory>
#include<functional>
#include<atomic>
using namespace std;
struct Date
{
	int _year;
	int _month;
	int _day;
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year), _month(month)
		, _day(day)
	{}
	~Date()
	{
		cout << "~Date()" << endl;
	}
};
namespace sy
{
	template<class T>
	class auto_ptr
	{
	public:
		auto_ptr(T* ptr)
			:_ptr(ptr)
		{}

		//p2(p1)
		//拷⻉时把被拷⻉对象的资源的管理权转移给拷⻉对象
		auto_ptr(auto_ptr<T>& sp)
			:_ptr(sp._ptr)
		{
			// 管理权转移
			sp._ptr = nullptr;
		}
		// p1 = p2;
		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
			// 检测是否为⾃⼰给⾃⼰赋值
			if (this != &ap)
			{
				// 释放当前对象中资源
				if (_ptr)
					delete _ptr;
				// 转移ap中资源到当前对象中
				_ptr = ap._ptr;
				ap._ptr = NULL;
			}
			return *this;
		}
		~auto_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		// 像指针⼀样使⽤
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};

	template<class T>
	class unique_ptr
	{
	public:
		//explicit 防⽌普通指针隐式类型转换成智能指针对象
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{}
		~unique_ptr() 
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		// 像指针⼀样使⽤
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
		//不⽀持拷⻉，只⽀持移动
		unique_ptr(const unique_ptr<T>& sp) = delete;
		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;

		unique_ptr(unique_ptr<T>&& sp)
			:_ptr(sp._ptr)
		{
			sp._ptr = nullptr;
		}
		unique_ptr<T>& operator=(unique_ptr<T>&& sp)
		{
			delete _ptr;
			_ptr = sp._ptr;
			sp._ptr = nullptr;
		}
	private:
		T* _ptr;
	};
	template<class T>
	class shared_ptr
	{
	public:
		explicit shared_ptr(T* ptr = nullptr)
			: _ptr(ptr)
			, _pcount(new atomic<int>(1))
		{}
		//删除器
		template<class D>
		shared_ptr(T* ptr, D del)
			: _ptr(ptr)
			, _pcount(new atomic<int>(1))
			, _del(del)
		{}
		//⽀持拷⻉，也⽀持移动
		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
			, _del(sp._del)
		{
			++(*_pcount);
		}
		void release()
		{
			if (--(*_pcount) == 0)
			{
				// 最后⼀个管理的对象，释放资源
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		}
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				release();
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
				_del = sp._del;
			}
			return *this;
		}
		~shared_ptr()
		{
			release();
		}
		T* get() const
		{
			return _ptr;
		}
		int use_count() const
		{
			return *_pcount;
		}
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
		//int* _pcount;
		atomic<int>* _pcount; // 原子操作
		function<void(T*)> _del = [](T* ptr) {delete ptr; }; 
	};
	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
		{}
		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}
		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}
	private:
		T * _ptr = nullptr;
	};
}

//int main()
//{
//	sy::auto_ptr<Date> ap1(new Date);
//	// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
//	sy::auto_ptr<Date> ap2(ap1);
//
//	// 空指针访问，ap1对象已经悬空 error
//	//ap1->_year++;
//
//	sy::unique_ptr<Date> up1(new Date);
//	// 不⽀持拷⻉
//	//unique_ptr<Date> up2(up1);
//	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
//	sy::unique_ptr<Date> up3(move(up1));
//	sy::shared_ptr<Date> sp1(new Date);
//
//	// ⽀持拷⻉ 也支持移动
//	sy::shared_ptr<Date> sp2(sp1);
//	sy::shared_ptr<Date> sp3(sp2);
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//	return 0;
//}

struct ListNode
{
	int _data;
	/*std::shared_ptr<ListNode> _next;
	std::shared_ptr<ListNode> _prev;*/
	// 这⾥改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
	// 不增加n2的引⽤计数，不参与资源释放的管理，就不会形成循环引⽤了
	std::weak_ptr<ListNode> _next;
	std::weak_ptr<ListNode> _prev;
	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};
//int main()
//{
//	// 循环引⽤ -- 内存泄露
//	std::shared_ptr<ListNode> n1(new ListNode);
//	std::shared_ptr<ListNode> n2(new ListNode);
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//	n1->_next = n2;
//	n2->_prev = n1;
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	// weak_ptr不⽀持管理资源，不⽀持RAII
//	// weak_ptr是专⻔绑定shared_ptr，不增加他的引⽤计数，作为⼀些场景的辅助管理
//	//std::weak_ptr<ListNode> wp(new ListNode);
//	return 0;
//}

////过期为非0 1
//int main()
//{
//	std::shared_ptr<string> sp1(new string("111111"));
//	std::shared_ptr<string> sp2(sp1);
//	std::weak_ptr<string> wp = sp1;
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	// sp1和sp2都指向了其他资源，则weak_ptr就过期了
//	sp1 = make_shared<string>("222222");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	sp2 = make_shared<string>("333333");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	wp = sp1;
//
//
//	//std::shared_ptr<string> sp3 = wp.lock();
//	auto sp3 = wp.lock();
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//	*sp3 += "###";
//	cout << *sp1 << endl;
//	return 0;
//}
#include<thread>
#include<mutex>
struct AA
{
	int _a1 = 0;
	int _a2 = 0;
	~AA()
	{
		cout << "~AA()" << endl;
	}
};
//int main()
//{
//	sy::shared_ptr<AA> p(new AA);
//	const size_t n = 100000;
//	mutex mtx;
//	auto func = [&]()
//		{
//			for (size_t i = 0; i < n; ++i)
//			{
//				// 这⾥智能指针拷⻉会++计数
//				sy::shared_ptr<AA> copy(p);
//				{
//					unique_lock<mutex> lk(mtx);
//					copy->_a1++;
//					copy->_a2++;
//				}
//			}
//		};
//	thread t1(func);
//	thread t2(func);
//	t1.join();
//	t2.join();
//	cout << p->_a1 << endl;
//	cout << p->_a2 << endl;
//	cout << p.use_count() << endl;
//	return 0;
//}

int main()
{
	// 申请⼀个1G未释放，这个程序多次运⾏也没啥危害
	// 因为程序⻢上就结束，进程结束各种资源也就回收了
	char* ptr = new char[1024 * 1024 * 1024];
	cout << (void*)ptr << endl;
	return 0;
}